// ------------------------------------------------------------------------
// 版权信息
// 版权归重庆虫儿飞科技有限公司所有。
// 所有权利保留。
// 官方网站：https://netokit.com
// 许可证信息
// Neto.Kit 项目主要遵循 MIT 许可证和 Apache 许可证（版本 2.0）进行分发和使用。
// 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。
// 
// 使用条款
// 使用本代码应遵守相关法律法规和许可证的要求。
// 
// 免责声明
// 对于因使用本代码而产生的任何直接、间接、偶然、特殊或后果性损害，我们不承担任何责任。
// 
// 其他重要信息
// Neto.Kit 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。
// 有关 Neto.Kit 项目的其他详细信息，请参阅位于源代码树根目录中的 COPYRIGHT 和 DISCLAIMER 文件。
// 
// 更多信息
// 请访问 https://netokit.com 获取更多关于 Neto.Kit 项目的许可证和版权信息。
// ------------------------------------------------------------------------

namespace Neto.Db.SqlSugar.Paged;

/// <summary>
///     SqlSugar 分页扩展
/// </summary>
[SuppressSniffer]
public static class SqlSugarPagedExtensions
{
    /// <summary>
    ///     分页拓展
    /// </summary>
    /// <param name="query"></param>
    /// <param name="pageIndex">查询页数</param>
    /// <param name="pageSize">条数</param>
    /// <param name="isOffsetFetchPage">sqlserver下使用 OFFSET/FETCH NEXT 分页，默认true</param>
    /// <returns></returns>
    public static async Task<PagedList<TEntity>> ToPagedListAsync<TEntity>(this ISugarQueryable<TEntity> query,
        int pageIndex, int pageSize, bool isOffsetFetchPage = true)
    {
        RefAsync<int> totalCount = 0;
        List<TEntity> items;
        if (isOffsetFetchPage)
            //sqlserver下使用 OFFSET/FETCH NEXT 分页
            items = await query.ToOffsetPageAsync(pageIndex, pageSize, totalCount);
        else
            //sqlserver下使用 ROW_NUMBER 分页
            items = await query.ToPageListAsync(pageIndex, pageSize, totalCount);
        var totalPages = (int)Math.Ceiling(totalCount / (double)pageSize);
        return new PagedList<TEntity>
        {
            PageIndex = pageIndex,
            PageSize = pageSize,
            Items = items,
            TotalCount = (int)totalCount,
            TotalPages = totalPages,
            HasNextPages = pageIndex < totalPages,
            HasPrevPages = pageIndex - 1 > 0
        };
    }

    /// <summary>
    ///     分页拓展
    /// </summary>
    /// <param name="query">ISugarQueryable</param>
    /// <param name="pageIndex">查询页数</param>
    /// <param name="pageSize">条数</param>
    /// <param name="isOffsetFetchPage">sqlserver下使用 OFFSET/FETCH NEXT 分页，默认true</param>
    /// <returns></returns>
    public static PagedList<TEntity> ToPagedList<TEntity>(this ISugarQueryable<TEntity> query, int pageIndex,
        int pageSize, bool isOffsetFetchPage = true)
    {
        var totalCount = 0;
        List<TEntity> items;
        if (isOffsetFetchPage)
            //sqlserver下使用 OFFSET/FETCH NEXT 分页
            items = query.ToOffsetPage(pageIndex, pageSize, ref totalCount);
        else
            //sqlserver下使用 ROW_NUMBER 分页
            items = query.ToPageList(pageIndex, pageSize, ref totalCount);
        var totalPages = (int)Math.Ceiling(totalCount / (double)pageSize);
        return new PagedList<TEntity>
        {
            PageIndex = pageIndex,
            PageSize = pageSize,
            Items = items,
            TotalCount = totalCount,
            TotalPages = totalPages,
            HasNextPages = pageIndex < totalPages,
            HasPrevPages = pageIndex - 1 > 0
        };
    }

    /// <summary>
    ///     分页拓展
    /// </summary>
    /// <param name="query"></param>
    /// <param name="pageIndex">查询页数</param>
    /// <param name="pageSize">条数</param>
    /// <param name="isOffsetFetchPage">sqlserver下使用 OFFSET/FETCH NEXT 分页，默认true</param>
    /// <returns></returns>
    public static async Task<PagedList<ReturnTentity>> ToPagedListAsync<TEntity, ReturnTentity>(
        this ISugarQueryable<TEntity> query, int pageIndex, int pageSize, bool isOffsetFetchPage = true)
    {
        var pagelist = await query.ToPagedListAsync(pageIndex, pageSize, isOffsetFetchPage);

        return new PagedList<ReturnTentity>
        {
            PageIndex = pageIndex,
            PageSize = pageSize,
            Items = pagelist.Items.Adapt<List<ReturnTentity>>(),
            TotalCount = pagelist.TotalCount,
            TotalPages = pagelist.TotalPages,
            HasNextPages = pageIndex < pagelist.TotalPages,
            HasPrevPages = pageIndex - 1 > 0
        };
    }

    /// <summary>
    ///     分页拓展
    /// </summary>
    /// <param name="query">ISugarQueryable</param>
    /// <param name="pageIndex">查询页数</param>
    /// <param name="pageSize">条数</param>
    /// <param name="isOffsetFetchPage">sqlserver下使用 OFFSET/FETCH NEXT 分页，默认true</param>
    /// <returns></returns>
    public static PagedList<ReturnTentity> ToPagedList<TEntity, ReturnTentity>(this ISugarQueryable<TEntity> query,
        int pageIndex, int pageSize, bool isOffsetFetchPage = true)
    {
        var pagelist = query.ToPagedList(pageIndex, pageSize, isOffsetFetchPage);
        return new PagedList<ReturnTentity>
        {
            PageIndex = pageIndex,
            PageSize = pageSize,
            Items = pagelist.Items.Adapt<List<ReturnTentity>>(),
            TotalCount = pagelist.TotalCount,
            TotalPages = pagelist.TotalPages,
            HasNextPages = pageIndex < pagelist.TotalPages,
            HasPrevPages = pageIndex - 1 > 0
        };
    }

    /// <summary>
    ///     分页扩展
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <param name="list"></param>
    /// <param name="pageIndex">查询页数</param>
    /// <param name="pageSize">条数</param>
    /// <returns></returns>
    public static PagedList<TEntity> ToPagedList<TEntity>(this IList<TEntity> list, int totalCount, int pageIndex = 1,
        int pageSize = 20)
        where TEntity : new()
    {
        var totalPages = (int)Math.Ceiling(totalCount / (double)pageSize);

        return new PagedList<TEntity>
        {
            PageIndex = pageIndex,
            PageSize = pageSize,
            Items = list,
            TotalCount = totalCount,
            TotalPages = totalPages,
            HasNextPages = pageIndex < totalPages,
            HasPrevPages = pageIndex - 1 > 0
        };
    }

    /// <summary>
    ///     分页扩展
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <param name="list"></param>
    /// <param name="page">分页对象</param>
    /// <returns></returns>
    public static PagedList<TEntity> ToPagedList<TEntity>(this IList<TEntity> list, PageModel page)
        where TEntity : new()
    {
        return ToPagedList(list, page.TotalCount, page.PageIndex, page.PageSize);
    }

    ///// <summary>
    /////分页扩展
    ///// </summary>
    ///// <typeparam name="TEntity"></typeparam>
    ///// <param name="list">list</param>
    ///// <param name="pageIndex">查询页数</param>
    ///// <param name="pageSize">条数</param>
    ///// <returns></returns>
    //public static PagedList<TEntity> ToSqlSugarPagedList<TEntity>(this IQueryable<TEntity> list, int pageIndex = 1, int pageSize = 20)
    //{
    //    var totalPages = (int)Math.Ceiling(list.Count() / (double)pageSize);

    //    return new PagedList<TEntity>
    //    {
    //        PageIndex = pageIndex,
    //        PageSize = pageSize,
    //        Items = list.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList(),
    //        TotalCount = list.Count(),
    //        TotalPages = totalPages,
    //        HasNextPages = pageIndex < totalPages,
    //        HasPrevPages = pageIndex - 1 > 0
    //    };
    //}
}